package com.example.arve;

import java.util.List;

import android.content.Context;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.Size;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

/**
 * Description:
 * This class is for displaying what the camera is looking at. Still a few issues, but it's getting there.
 * 
 * What's working: 
 *  - Taking a picture
 *  - Restoring the camera when onpause/onresume occurs
 *  - Auto focus! (Sorta)
 *  
 * What's not:
 *  - There isn't any real rotation here yet, so when a user rotates their phone, the camera will just take
 *    a picture sideways
 *  - I think there's still an issue with the emulator? It used to freak out when onSurfaceChanged was called for reasons.
 *    Don't know if it's that way now as I've been using a phone for testing.
 *  - A few functions need to be taken from CameraActivity and placed in here, as this should be responsible for photo taking
 *    and the rest
 * @author Richard
 *
 */
public class CameraSurface extends SurfaceView implements SurfaceHolder.Callback
{
	//What the camera can see
	private SurfaceHolder camera_sight;
	//Reference to the camera
	private Camera active_camera;
	//The possible preview sizes
	private List<Size> possible_dimensions;
	//The preview size we're using
	private Size active_size;
	
	public CameraSurface(Context _context, Camera _camera) 
	{
		super(_context);

		//Set our camera
		active_camera = _camera;
		//The possible sizes of the preview
		possible_dimensions = active_camera.getParameters().getSupportedPreviewSizes();
		//Set our size
		active_size = possible_dimensions.get(0);
		
		//Setup our camera size
		Camera.Parameters params = active_camera.getParameters();
		params.setPreviewSize(active_size.width, active_size.height);
		//And our rotation so the images aren't saved sideways
		params.setRotation(90);
		//And force to format images as JPEG
		params.setPictureFormat(PixelFormat.JPEG);
		
		//And place them into the camera
		active_camera.setParameters(params);
		
		//And setup our surface view
		camera_sight = this.getHolder();
		camera_sight.addCallback(this);
		//Deprecated but still used
		camera_sight.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
		
		
		requestLayout();
		
	}

	@Override
	public void surfaceCreated(SurfaceHolder _holder) 
	{
		try
		{
			active_camera.setDisplayOrientation(90);
			//Setup the display
			active_camera.setPreviewDisplay(camera_sight);
			//And start the display so we can see what the camera sees
			active_camera.startPreview();
		
		}
		catch(Exception _error)
		{
			Log.e("CameraPreview: Surface Created", "Error setting camera preview: " + _error.getMessage());
		}
	}

	//Note: Need to fix this; keeps crashing in emulator; works for HTC one though
	@Override
	public void surfaceChanged(SurfaceHolder _holder, int _format, int _width, int _height) 
	{
		//If we don't have anything to get the surface from, why bother?
		if(camera_sight.getSurface() == null)
			return;
		
		try
		{	
			//Just need to stop our current display so we can reset it
			active_camera.stopPreview();
		}
		catch(Exception _error)
		{
			
		}
		
		try
		{
			Camera.Parameters params = active_camera.getParameters();
			params.setPreviewSize(active_size.width, active_size.height);
			active_camera.setParameters(params);
			requestLayout();
			//Resetting the preview for the camera display
			active_camera.setPreviewDisplay(camera_sight);
			active_camera.startPreview();
		}
		catch(Exception _error)
		{
			Log.e("CameraPreview: Surface Changed", "Error setting camera preview: " + _error.getMessage());
		}
	}
	
	public void resetCamera()
	{
		//Resets the surface view so that it doesn't freeze after a photo
		active_camera.startPreview();
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder _holder) 
	{
		// TODO Auto-generated method stub
		//active_camera.stopPreview();
	}

	public void takeCameraRef(Camera _camera) 
	{
		//Just for when we lose our camera
		active_camera = _camera;
		resetCamera();
	}
	
	public final Rect getFrameRect()
	{
		return camera_sight.getSurfaceFrame();
	}
}